#ifndef _SENT_H
#define _SENT_H

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

#include "structure.h"

using namespace std;

class sent {
   class entity {
      public:
	 string et, eid; // entity type and entity IDs
	 int id; 
	 int es, ee; // start and end of each entity
	 bool operator < (const entity &other) const {
	    if (es < other.es) return true;
	    if (ee < other.ee) return true;
	    return false;
	 }
   };
   class relation {
      public:
	 string rtype, reid1, reid2; // relation type, the two IDs of the entities
   };
   int ind; // index of the sentence

   // data before processing
   vector <string> word,pos; // original 
   vector <string> etype; // type of token ('O' or any entity type) 
   vector <string> rtype; // relation type
   vector <int> rs,re; // word indices of relation entities

   // data after processing
   vector <string> nword,npos; // after changing from "N/N" => N N
   vector <int> inword,inpos; // integer mapped words and pos tags
   vector <entity> ent;
   vector <relation> rel;

   // functions

   string ascii(const string &s) const; // to convert a token into ascii form
   string gFeature(const string &s) const; // a new token generated by 
                                           // replacing [a-z]* by a, 
					   // [A-Z]* by A and [0-9]* by 0

   void change(bool onlyAdjacent); // processes data

   void split(const string &s, vector <string> &st) const; 
   // splits the string s by '/' character
   

   public:
   void countCrissCrosses() const;
   bool read(ifstream &in, bool onlyAdjacent);

   structure giveStructure() const;

   int entSize() const {
      return ent.size();
   }
   int relSize() const {
      return rel.size();
   }

   void giveEntities(vector <string> &s, vector <int> &st, vector <int> &en) const;
   void giveCandidateEntities(vector <int> &st, vector <int> &en) const;

   int giveWord(int i) const {
      return inword[i];
   }
   int givePostag(int i) const {
      return inpos[i];
   }

   vector <int> giveWords() const {
      return inword;
   }
   vector <int> givePostags() const {
      return inpos;
   }

   void writeSent(ostream &out) const;

   ostream& write(ostream &out) const; 
};

inline ostream& operator << (ostream &out, const sent &s) {
   return s.write(out);
}

#endif
